package org.jeecg.modules.wechat.controller;


import org.apache.commons.lang3.StringUtils;
import org.jeecg.modules.wechat.config.WechatThirdConfig;
import org.jeecg.modules.wechat.error.WechatErrorException;
import org.jeecg.modules.wechat.message.WechatMpXmlMessage;
import org.jeecg.modules.wechat.message.WechatMpXmlOutMessage;
import org.jeecg.modules.wechat.message.WechatThirdXmlMessage;
import org.jeecg.modules.wechat.result.auth.ApiQueryAuthInfo;
import org.jeecg.modules.wechat.service.WechatNotifyService;
import org.jeecg.modules.wechat.service.WechatThirdAuthService;
import org.jeecg.modules.wechat.util.FastJsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * @author
 * @date 2018/12/4
 */
@RestController
@RequestMapping("/wechat/third/notify")
public class WechatNotifyController {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Autowired
    private WechatNotifyService wechatNotifyService;
    @Autowired
    private WechatThirdConfig wechatThirdConfig;
    @Autowired
    private WechatThirdAuthService wechatThirdAuthService;


    /**
     * 微信授权事件的接收
     * @param requestBody
     * @param timestamp
     * @param nonce
     * @param signature
     * @param encType
     * @param msgSignature
     * @return
     */
    @RequestMapping("/receive_ticket")
    public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,
                                @RequestParam("nonce") String nonce, @RequestParam("signature") String signature,
                                @RequestParam(name = "encrypt_type", required = false) String encType,
                                @RequestParam(name = "msg_signature", required = false) String msgSignature) {
        this.logger.info(
                "\n接收微信请求：[signature=[{}], encType=[{}], msgSignature=[{}],"
                        + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                signature, encType, msgSignature, timestamp, nonce, requestBody);

        if (!StringUtils.equalsIgnoreCase("aes", encType)
                || !wechatNotifyService.checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }

        // aes加密的消息
        WechatThirdXmlMessage inMessage = WechatThirdXmlMessage.fromEncryptedXml(requestBody,
                wechatThirdConfig, timestamp, nonce, msgSignature);
        this.logger.info("\n消息解密后内容为：\n{} ", inMessage.toString());
        try {
            String out = wechatNotifyService.route(inMessage);
            this.logger.info("\n组装回复信息：{}", out);
        } catch (WechatErrorException e) {
            this.logger.error("receive_ticket", e);
        }


        return "success";
    }


    /**
     * 消息与事件接收URL
     * @param requestBody
     * @param appId
     * @param signature
     * @param timestamp
     * @param nonce
     * @param openid
     * @param encType
     * @param msgSignature
     * @return
     */
    @RequestMapping(value ="/{appId}/callback", method = RequestMethod.POST)
    public Object callback(@RequestBody(required = false) String requestBody,
                           @PathVariable("appId") String appId,
                           @RequestParam("signature") String signature,
                           @RequestParam("timestamp") String timestamp,
                           @RequestParam("nonce") String nonce,
                           @RequestParam("openid") String openid,
                           @RequestParam("encrypt_type") String encType,
                           @RequestParam("msg_signature") String msgSignature) {
        this.logger.info(
                "\n callback接收微信请求：[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
                        + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
                appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
        if (!StringUtils.equalsIgnoreCase("aes", encType)
                || !wechatNotifyService.checkSignature(timestamp, nonce, signature)) {
            throw new IllegalArgumentException("非法请求，可能属于伪造的请求！");
        }
        String out = "";
        // aes加密的消息
        WechatMpXmlMessage wechatMpXmlMessage=WechatMpXmlMessage.fromEncryptedMpXml(requestBody,wechatThirdConfig,timestamp,nonce,msgSignature);
        this.logger.info("\n消息解密后内容为：\n{} ", wechatMpXmlMessage.toString());
        // 全网发布测试用例
        try {
            if (StringUtils.equals(wechatMpXmlMessage.getMsgType(), "text")) {
                /*返回普通文本信息*/
                if (StringUtils.equals(wechatMpXmlMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {
                    String returnContent = wechatMpXmlMessage.getContent()+"_callback";
                    Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
                    WechatMpXmlOutMessage wechatMpXmlOutMessage=WechatMpXmlOutMessage.builder()
                            .content(returnContent)
                            .fromUserName(wechatMpXmlMessage.getToUser())
                            .toUserName(wechatMpXmlMessage.getFromUser())
                            .createTime(createTime)
                            .msgType("text")
                            .build();
                    out=WechatMpXmlOutMessage.wechatMpOutXmlMessageToEncryptedXml(wechatMpXmlOutMessage,wechatThirdConfig);
                }else if (StringUtils.startsWith(wechatMpXmlMessage.getContent(), "QUERY_AUTH_CODE:")) {
                    /*全网发布返回api文本信息*/
                    String authCode=wechatMpXmlMessage.getContent().split(":")[1];
                    ApiQueryAuthInfo apiQueryAuthInfo= wechatThirdAuthService.getApiQueryAuthInfo(authCode);
                    Map<String,Object> obj = new HashMap<String,Object>();
                    Map<String,Object> msgMap = new HashMap<String,Object>();
                    String msg = authCode + "_from_api";
                    msgMap.put("content", msg);
                    obj.put("touser", wechatMpXmlMessage.getFromUser());
                    obj.put("msgtype", "text");
                    obj.put("text", msgMap);
                    out = wechatThirdAuthService.sendMessage(FastJsonUtils.map2json(obj), apiQueryAuthInfo.getAuthorizationInfo().getAuthorizerAccessToken());
                }
            } else if (StringUtils.equals(wechatMpXmlMessage.getMsgType(), "event")) {
                /*发送事件信息(返回文本信息)*/
                String content = wechatMpXmlMessage.getEvent() + "from_callback";
                Long createTime = Calendar.getInstance().getTimeInMillis() / 1000;
                WechatMpXmlOutMessage wechatMpXmlOutMessage=WechatMpXmlOutMessage.builder()
                        .content(content)
                        .fromUserName(wechatMpXmlMessage.getToUser())
                        .toUserName(wechatMpXmlMessage.getFromUser())
                        .createTime(createTime)
                        .msgType("text")
                        .build();
                out=WechatMpXmlOutMessage.wechatMpOutXmlMessageToEncryptedXml(wechatMpXmlOutMessage,wechatThirdConfig);
            }
        }catch (Exception e) {
            logger.error("callback", e);
        }
        logger.info("\n消息与事件接收URL：out=[{}] ",out);
        return "";
    }



}
